Security hardening: encrypt wallet secrets at rest + fix exec/IPC/XSS/nav, dedupe @bsv/sdk - #53
Merged
Merged
Conversation
…nifest proxy Non-breaking fixes from docs/SECURITY_REVIEW.md: - #2 exec -> execFile (no shell interpolation) in sslCert.ts and main.ts; validate restored bundle identifier. - #3 allow-list the storage:call-method IPC to the methods StorageElectronIPC actually calls; reject everything else. - #4 sanitize update release notes with DOMPurify before dangerouslySetInnerHTML. - #6/#10 only http(s) reaches shell.openExternal; add will-redirect handler; block javascript:/file:/data:/custom protocols. - #9 re-validate the resolved URL (https + /manifest.json) after redirects. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move snap/primaryKeyHex/mnemonic12 out of renderer localStorage into a main-process file encrypted with Electron safeStorage. Toolbox snapshots store their AES key inside the blob, so they offer no at-rest protection today. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hydrate the secret cache at boot before the wallet tree mounts, migrate legacy plaintext localStorage on first run, and replace every snap/ primaryKeyHex/mnemonic12 localStorage access with the secrets facade. logout() now clears the secret store explicitly since localStorage.clear() no longer reaches the secrets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wallet-toolbox / wallet-toolbox-client -> 2.1.30 (pin @bsv/sdk ^2.1.3), @bsv/sdk -> 2.1.6. Collapses the duplicate @bsv/sdk that nested 2.1.2 under wallet-toolbox-client, which had caused the LookupResolver type clash in WalletService.ts and broke `tsc`/build:renderer. Renderer tsc now 0 errors; full test suite green (69 passed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
localStorage.snap/primaryKeyHex/mnemonic12were effectively plaintext on disk.docs/SECURITY_REVIEW.md([BUG] Recovery Key Error #2, [BUG] Adding new profile #3, [BUG] Returning account, Unable to login with Mnemonic #4, Windows update and local backup #6/BSV Desktop doesn't display on Wayland - requires X11 workaround #10, Feature Request: One-Click SSL Certificate Installation #9).@bsv/sdkacross the stack, fixing a pre-existingtsc/build:rendererfailure.Changes
Secrets at rest (#5)
electron/secretStore.ts— main-process store atuserData/secrets.dat, per-entry ElectronsafeStorageciphertext (key in OS keychain, not beside the data). Name allow-list, atomic writes, warned plaintext fallback when no OS keyring (incl. Linuxbasic_text).secrets:get-all/set/deleteIPC + preload + types.src/lib/services/secrets.ts— synchronous renderer facade over a cache hydrated once at boot; one-time migration of legacy plaintextlocalStorage, cleared after.main.tsxawaits hydration before mount; all ~30 call sites routed through the facade;logout()now clears the store (localStorage.clear() no longer reaches it).Non-breaking hardening
exec->execFile(no shell interpolation) insslCert.ts/main.ts; validate restored bundle id.storage:call-methodIPC to methodsStorageElectronIPCactually calls.dangerouslySetInnerHTML.shell.openExternal; addwill-redirect; blockjavascript:/file:/data:/custom./manifest.json) after redirects.Deps
@bsv/*to latest;@bsv/sdk-> 2.1.6, toolbox(-client) -> 2.1.30. Collapses the duplicate@bsv/sdk(nested 2.1.2) that caused theLookupResolvernominal-type clash inWalletService.ts.Docs
docs/superpowers/;docs/SECURITY_REVIEW.mdremediation status updated.Test plan
npx vitest run --config vitest.config.electron.ts— 69 passed (incl. newsecretStore/secrets.renderersuites)npm run build:renderer— green (was red pre-dedupe); renderertsc0 errorsnpm run build:electron— green,secretStore.jsemittedsecrets.dat; upgrade migrates+clears legacy plaintext; logout forgets wallet; Linux-no-keyring falls back with warning🤖 Generated with Claude Code